package com.onesports.intelligent.k12.polarlight.service.student;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.onesports.intelligent.k12.polarlight.common.errors.exceptions.BusinessException;
import com.onesports.intelligent.k12.polarlight.domain.dto.student.StudentSaveDTO;
import com.onesports.intelligent.k12.polarlight.domain.entity.course.ClassInfo;
import com.onesports.intelligent.k12.polarlight.domain.entity.course.ClassStudent;
import com.onesports.intelligent.k12.polarlight.domain.entity.student.Student;
import com.onesports.intelligent.k12.polarlight.domain.entity.student.UserStudentRel;
import com.onesports.intelligent.k12.polarlight.domain.vo.student.StudentVO;
import com.onesports.intelligent.k12.polarlight.enums.ClassInfoStatusEnum;
import com.onesports.intelligent.k12.polarlight.security.SecurityUtils;
import com.onesports.intelligent.k12.polarlight.service.grade.ClassInfoService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author FPH
 * @since 2022年7月13日09:27:12
 */
@Service
@RequiredArgsConstructor
public class MyStudentService {
    private final StudentService studentService;
    private final UserStudentRelService userStudentMapService;

    private final ClassInfoService classInfoService;

    private final ClassStudentService classStudentService;

    /**
     * 查询学生集合
     * @param userId
     * @return
     */
    public List<StudentVO> getStudentByUserId(String userId){
        List<String> idList = userStudentMapService.getStudentIdListByUserId(userId);
        if(CollectionUtils.isEmpty(idList)){
            return new ArrayList<StudentVO>();
        }
        return studentService.queryStudentByIds(idList);
    }

    /**
     * 添加学员
     * @param studentSaveDTO
     * @return
     */
    public Boolean saveStudent(StudentSaveDTO studentSaveDTO){
        //判断学生名字是否重复,先获取当前账户的学生集合的名称
        List<StudentVO> studentByUserId = getStudentByUserId(SecurityUtils.getAccountId());
        if(CollectionUtils.isNotEmpty(studentByUserId)){
            List<StudentVO> collect = studentByUserId.stream().filter(i -> i.getStudentName().equals(studentSaveDTO.getStudentName())).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(collect)){
                throw new BusinessException("孩子名称重复");
            }
        }
        //student表判断是否存在此电话号码(一个名字一个电话号码一定只有一个学生)
        Student student = studentService.list(new LambdaQueryWrapper<Student>().eq(Student::getStudentName, studentSaveDTO.getStudentName())
                .eq(Student::getContactPhone, SecurityUtils.getPhone())).stream().findFirst().orElse(new Student());
        if(StringUtils.isNotEmpty(student.getIdCard())){
            //判断这个学员是否被其他家长关联，如果被其他家长返回已被绑定的信息
            List<UserStudentRel> list = userStudentMapService.list(new LambdaQueryWrapper<UserStudentRel>()
                    .eq(UserStudentRel::getStudentId, student.getId()));
            if(CollectionUtils.isNotEmpty(list)){
                throw new BusinessException("该学员已被绑定");
            }else{
                //如果没有被关联，则更新这个学生的其他信息，再插入关联表
                BeanUtils.copyProperties(studentSaveDTO,student);
                student.setAge(getAgeByBirth(student.getBirthday()));
                if (Boolean.FALSE.equals(studentService.updateById(student))) {
                    throw new BusinessException("学生信息更新失败");
                }
            }
        }else {
            BeanUtils.copyProperties(studentSaveDTO,student);
            student.setContactName(SecurityUtils.getNickname());
            student.setContactPhone(SecurityUtils.getPhone());
            //计算当前年龄
            student.setAge(getAgeByBirth(student.getBirthday()));
            if (Boolean.FALSE.equals(studentService.save(student))) {
                throw new BusinessException("学生表插入失败");
            }
        }
        UserStudentRel userStudentRel = new UserStudentRel();
        userStudentRel.setStudentId(student.getId());
        userStudentRel.setUserId(SecurityUtils.getAccountId());
        if (Boolean.FALSE.equals(userStudentMapService.save(userStudentRel))) {
            throw new BusinessException("关联表插入失败");
        }
        return true;
    }


    /**
     * 计算年龄
     * @param birthday
     * @return
     */
    private static int getAgeByBirth(Date birthday) {
        int age = 0;
        try {
            Calendar now = Calendar.getInstance();
            // 当前时间
            now.setTime(new Date());
            Calendar birth = Calendar.getInstance();
            birth.setTime(birthday);
            //如果传入的时间，在当前时间的后面，返回0岁
            if (birth.after(now)) {
                age = 0;
            } else {
                age = now.get(Calendar.YEAR) - birth.get(Calendar.YEAR);
                if (now.get(Calendar.DAY_OF_YEAR) > birth.get(Calendar.DAY_OF_YEAR)) {
                    age += 1;
                }
            }
            return age;
        } catch (Exception e) {
            return 0;
        }
    }

    /**
     * 删除学员
     * @param studentId
     */
    public Boolean removeStudent(String studentId){
        //判断学生是否在拼班、待开课、开班中
        List<String> classIdList = classStudentService.list(new LambdaQueryWrapper<ClassStudent>()
                        .eq(ClassStudent::getStudentId, studentId))
                .stream().map(ClassStudent::getClassInfoId).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(classIdList)){
            List<String> statusList = classInfoService.list(new LambdaQueryWrapper<ClassInfo>().in(ClassInfo::getId, classIdList)).stream().map(ClassInfo::getClassStatus).collect(Collectors.toList());
            statusList.forEach(i->{
                if (i.equals(ClassInfoStatusEnum.IN_CLASS.getValue())
                        ||i.equals(ClassInfoStatusEnum.FINISH_CLASS.getValue())
                        ||i.equals(ClassInfoStatusEnum.OPEN_CLASS.getValue())) {
                    throw new BusinessException("该学员在班级中，不允许删除");
                }
            });
        }
        return userStudentMapService.remove(new LambdaQueryWrapper<UserStudentRel>()
                .eq(UserStudentRel::getStudentId,studentId)
                .eq(UserStudentRel::getUserId,SecurityUtils.getAccountId()));
    }

}
